package com.tairanchina.md.meeting.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;



/**
 * 对象转换工具类
 *
 * @author luoweifei
 * @author yinjie-taixuan
 */
public class CommonConvertUtil
{
    /**
     * 对象转换,将P类型对象转成R类型对象。用于Dao层与Service层之间的转化。<br>
     * 两对象间字段名字必须一致<br>
     *
     * @param p
     * @return
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     */
    public static <R, P> R convert(P p, R r)
    {
        if (p == null || r == null)
        {
            return null;
        }
        Class<? extends Object> classP = p.getClass();
        Class<? extends Object> classR = r.getClass();
        Field[] fields = classP.getDeclaredFields();
        for (Field pfield : fields)
        {
            Field rfield;
            try
            {
                for (int i = 0; i < r.getClass().getDeclaredFields().length; i++)
                {
                    // 序列化接口要求的final字段不需要转换
                    if ("serialVersionUID".equals(r.getClass().getDeclaredFields()[i].getName()))
                    {
                        continue;
                    }

                    String tempFileldNameR = r.getClass().getDeclaredFields()[i].getName();
                    String tempFileldNameP = pfield.getName();
                    String tempFileldTypeR = r.getClass().getDeclaredFields()[i].getType().getName();
                    String tempFileldTypeP = pfield.getType().getName();
                    pfield.setAccessible(true);
                    Object tempValue = pfield.get(p);

                    if (tempFileldNameR.equals(tempFileldNameP)
                            && tempFileldTypeR.equals(tempFileldTypeP)
                            && tempValue != null)
                    {
                        rfield = r.getClass().getDeclaredField(pfield.getName());
                        String name = "set" + rfield.getName().substring(0, 1).toUpperCase()
                                + rfield.getName().substring(1);
                        Method method = classR.getDeclaredMethod(name, pfield.getType());
                        method.invoke(r, tempValue);
                    }
                }
            }
            catch (NoSuchMethodException noSuchMethodException)
            {
                noSuchMethodException.printStackTrace();
            }
            catch (Exception e)
            {
                throw new RuntimeException(String.format("转换%s到%s对象失败！", p.toString(), r.toString()), e);
            }
        }

        return r;
    }

    /**
     * @param listInput
     * @param r 返回的类型的一个实例 ，new 一个传进去就可以
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <R, P> List<R> convert(List<P> listInput, R r)
    {
        if (listInput == null || listInput.isEmpty() || r == null)
        {
            return null;
        }
        List<R> rlist = new ArrayList<>();
        for (P p : listInput)
        {
            try
            {
                rlist.add((R) convert(p, r.getClass().newInstance()));
            }
            catch (InstantiationException e)
            {
                e.printStackTrace();
            }
            catch (IllegalAccessException e)
            {
                e.printStackTrace();
            }

        }
        return rlist;
    }
}
